home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
Games
/
reve
/
xview.c
< prev
Wrap
C/C++ Source or Header
|
1995-05-03
|
30KB
|
1,110 lines
/*LINTLIBRARY*/
/* @(#)xview.c 1.23 91/11/13
*
* XView dependent graphics routines used by reve.
*
* Copyright (c) 1990, 1991 - Rich Burridge & Yves Gallot.
* All rights reserved.
*
* Permission is granted to copy this source, for redistribution
* in source form only, provided the news headers in "substantially
* unaltered format" are retained, the introductory messages are not
* removed, and no monies are exchanged.
*
* Permission is also granted to copy this source, without the
* news headers, for the purposes of making an executable copy by
* means of compilation, provided that such copy will not be used
* for the purposes of competition in any othello tournaments, without
* prior permission from the authors.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if reported
* (see README file), then an attempt will be made to fix them.
*/
#include "reve.h"
#include "color.h"
#include "extern.h"
#include "images.h"
#include <ctype.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/panel.h>
#include <xview/cms.h>
#include <xview/cursor.h>
#include <xview/svrimage.h>
#include <xview/textsw.h>
#include <xview/xv_xrect.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include "reve_ui.h"
#define XV_SET (void) xv_set
#define CLIENT_NO 10
#define FRAME_BORDER_SIZE 7
#define FRAME_LABEL_SIZE 30
#define BOARDFONT "lucidasanstypewriter-10"
#define BOLDFONT "lucidasanstypewriter-bold-12"
#define DEFFONT "fixed"
#define HELPFONT "lucidasanstypewriter-12"
#define NORMALFONT "lucidasanstypewriter-12"
enum popup_pos { P_BELOW, P_RIGHT } ; /* Positions relative to main frame. */
Canvas_paint_window gpw ;
Event *cur_event ;
Notify_client client = (Notify_client) CLIENT_NO ;
reve_Wmain_objects *Reve_Wmain ;
reve_Wdepth_objects *Reve_Wdepth ;
reve_Wprops_objects *Reve_Wprops ;
reve_Whelp_objects *Reve_Whelp ;
reve_Wload_objects *Reve_Wload ;
reve_Wsave_objects *Reve_Wsave ;
reve_Wboard_objects *Reve_Wboard ;
Attr_attribute INSTANCE ;
Server_image hglass_pr, nocur_pr ;
Xv_Cursor cursor[MAXCURSORS] ;
Display *dpy ; /* Display id of reve frame. */
Drawable images[MAXIMAGES] ; /* Various graphics images used by reve. */
Drawable xid ; /* Xid for reve canvas. */
GC gc ; /* Graphics context for text and lines. */
GC igc ; /* Graphics content for 1bit images. */
GC ropgc ; /* Graphics context for rops. */
GC stencilgc ; /* Graphics context for stencils. */
Window root ;
XFontStruct *font[MAXFONTS] ; /* Xlib handles to the fonts. */
XGCValues gc_val ; /* Used to setup graphics context values. */
XrmDatabase reve_DB ; /* Combined resources database. */
int screen ; /* Default graphics display screen. */
unsigned long backgnd ; /* Default background color. */
unsigned long foregnd ; /* Default foreground color. */
unsigned long gc_mask ; /* Mask for setting graphic context values. */
unsigned long palette[REVE_COLORSIZE] ; /* Xlib color palette. */
int opvals[3] ; /* Graphics rasterop values. */
static Drawable make_server_image P((unsigned char *)) ;
static Notify_value check_clock P((Notify_client, int)) ;
static Notify_value quit_proc P((Notify_client, Destroy_status)) ;
static Notify_value read_from_fd P((Notify_client, int)) ;
static Notify_value sigchldcatcher P((Notify_client, int,
union wait *, struct rusage *)) ;
static XFontStruct *get_font P((char *, char *)) ;
Menu_item menu_do P((Menu_item, Menu_generate)) ;
Notify_value canvas_proc P((Xv_window, Event *,
Notify_arg, Notify_event_type)) ;
void button_do P((Panel_item, Event *)) ;
void canvas_resize_proc P((Canvas, int, int)) ;
void destroy_reve P(()) ;
void reset_props P((Panel_item, Event *)) ;
void set_depth P((Panel_item, int, Event *)) ;
void set_profmax P((Panel_item, Event *)) ;
void set_props P((Panel_item, Event *)) ;
void xv_start_load P((Panel_item, Event *)) ;
void xv_start_save P((Panel_item, Event *)) ;
static void change_depth P((int)) ;
static void connect_to_reve P((int)) ;
static void load_colors P(()) ;
static void set_interval_timer P(()) ;
void
batch(state) /* Turn graphics batching on or off. */
enum bltype state ;
{
XSync(dpy, 0) ;
}
void
beep()
{
XBell(dpy, 56) ;
XFlush(dpy) ;
}
/*ARGSUSED*/
void
button_do(item, event)
Panel_item item ;
Event *event ;
{
char *label ;
label = (char *) xv_get(item, PANEL_LABEL_STRING) ;
if (EQUAL(label, "Help..."))
position_popup(Reve_Wmain->Wmain, Reve_Whelp->Whelp, P_RIGHT) ;
else if (EQUAL(label, "Props..."))
position_popup(Reve_Wmain->Wmain, Reve_Wprops->Wprops, P_RIGHT) ;
}
/*ARGSUSED*/
Notify_value
canvas_proc(win, event, arg, type)
Xv_window win ;
Event *event ;
Notify_arg arg ;
Notify_event_type type ;
{
cur_event = event ; /* Determine what kind of event it is. */
handle_event() ; /* And do the appropriate action. */
update_clock(next_player, FALSE) ;
return(notify_next_event_func(win, (Notify_event) event, arg, type)) ;
}
void
canvas_resize_proc(canvas, width, height)
Canvas canvas ;
int width, height ;
{
width = (int) xv_get(Reve_Wboard->Bcanvas, XV_WIDTH) ;
height = (int) xv_get(Reve_Wboard->Bcanvas, XV_HEIGHT) ;
if (board_width != width || board_height != height)
{
board_width = width ;
board_height = height ;
make_pieces(board_width, board_height) ;
paint_board() ;
}
}
static void
change_depth(depth)
int depth ;
{
struct reve_in in ;
in.type = M_PROFMAX ;
in.level = depth ;
WRITE(pipe_io[0][1], (char *) &in, sizeof(struct reve_in)) ;
}
static Notify_value
check_clock(client, itimer_type)
Notify_client client ;
int itimer_type ;
{
update_clock(next_player, FALSE) ;
return(NOTIFY_DONE) ;
}
void
close_reve()
{
XV_SET(Reve_Wboard->Wboard, FRAME_CLOSED, TRUE, 0) ;
}
/*ARGSUSED*/
void
color_area(wtype, x, y, width, height, color)
enum win_type wtype ;
int x, y, width, height, color ;
{
if (iscolor) gc_val.foreground = palette[color] ;
else
{
if (color == C_WHITE) gc_val.foreground = backgnd ;
else gc_val.foreground = foregnd ;
}
gc_val.function = GXcopy ;
gc_mask = GCForeground | GCFunction ;
XChangeGC(dpy, gc, gc_mask, &gc_val) ;
XFillRectangle(dpy, xid, gc,
x, y, (unsigned int) width, (unsigned int) height) ;
}
void
connect_io() /* Connect to computer process and possible remote human. */
{
if (pipe_io[1][0] > 0)
notify_set_input_func(client, read_from_fd, pipe_io[1][0]) ;
if (socketfd > 0)
notify_set_input_func(client, read_from_fd, socketfd) ;
notify_set_wait3_func(client, sigchldcatcher, pid) ;
}
void
destroy_reve(item, event) /* Terminate Reve. */
Panel_item item ;
Event *event ;
{
xv_destroy_safe(Reve_Wmain->Wmain) ;
KILL(pid, SIGKILL) ;
exit(0) ;
}
/*ARGSUSED*/
void
draw_image(wtype, x, y, width, height, image)
enum win_type wtype ;
int x, y, width, height ;
enum image_type image ;
{
gc_mask = GCStipple | GCTileStipXOrigin | GCTileStipYOrigin ;
gc_val.stipple = images[(int) image] ;
gc_val.ts_x_origin = x ;
gc_val.ts_y_origin = y ;
XChangeGC(dpy, ropgc, gc_mask, &gc_val) ;
XFillRectangle(dpy, xid, ropgc, x, y, width, height) ;
}
/*ARGSUSED*/
void
draw_line(wtype, x1, y1, x2, y2, op, color)
enum win_type wtype ;
int x1, y1, x2, y2, color ;
enum optype op ;
{
if (iscolor) gc_val.foreground = palette[color] ;
else
{
if (color == C_WHITE) gc_val.foreground = backgnd ;
else gc_val.foreground = foregnd ;
}
gc_val.function = opvals[(int) op] ;
XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
XDrawLine(dpy, xid, gc, x1, y1, x2, y2) ;
}
/*ARGSUSED*/
void
draw_stencil(wtype, x, y, width, height, op, color, stencil, image)
enum win_type wtype ;
int x, y, width, height, color ;
enum optype op ;
enum image_type stencil, image ;
{
if (iscolor) gc_val.foreground = palette[color] ;
else gc_val.foreground = foregnd ;
gc_val.function = opvals[(int) op] ;
gc_val.clip_x_origin = x ;
gc_val.clip_y_origin = y ;
gc_val.clip_mask = images[(int) stencil] ;
gc_val.stipple = images[(int) image] ;
gc_val.ts_x_origin = x ;
gc_val.ts_y_origin = y ;
gc_mask = GCForeground | GCFunction | GCClipMask |
GCClipXOrigin | GCClipYOrigin |
GCStipple | GCTileStipXOrigin | GCTileStipYOrigin ;
XChangeGC(dpy, stencilgc, gc_mask, &gc_val) ;
XFillRectangle(dpy, xid, stencilgc, x, y, width, height) ;
}
/*ARGSUSED*/
void
draw_text(wtype, x, y, ftype, color, str)
enum win_type wtype ;
enum font_type ftype ;
int x, y, color ;
char *str ;
{
if (iscolor) gc_val.foreground = palette[color] ;
else
{
if (color == C_WHITE) gc_val.foreground = backgnd ;
else gc_val.foreground = foregnd ;
}
gc_val.font = font[(int) ftype]->fid ;
gc_val.function = GXcopy ;
XChangeGC(dpy, gc, GCFont | GCForeground | GCFunction, &gc_val) ;
XDrawString(dpy, xid, gc, x, y, str, strlen(str)) ;
}
static XFontStruct *
get_font(name, defname)
char *name, *defname ;
{
XFontStruct *f ;
if (name == NULL || !(f = XLoadQueryFont(dpy, name)))
if (!(f = XLoadQueryFont(dpy, defname)))
if (!(f = XLoadQueryFont(dpy, DEFFONT)))
{
FPRINTF(stderr, "%s: couldn't get the default font.", progname) ;
exit(1) ;
}
return(f) ;
}
char *
get_resource(rtype) /* Get Reve resource from merged databases. */
enum res_type rtype ;
{
char cstr[MAXLINE], nstr[MAXLINE], str[MAXLINE] ;
char *str_type[20] ;
XrmValue value ;
STRCPY(str, resources[(int) rtype]) ;
SPRINTF(nstr, "reve.%s", str) ;
if (islower(str[0])) str[0] = toupper(str[0]) ;
SPRINTF(cstr, "Reve.%s", str) ;
if (XrmGetResource(reve_DB, nstr, cstr, str_type, &value) == NULL)
return((char *) NULL) ;
else return(value.addr) ;
}
int
get_strwidth(ftype, str) /* Get width in pixels of string value. */
enum font_type ftype ;
char *str ;
{
return(XTextWidth(font[(int) ftype], str, strlen(str))) ;
}
void
init_fonts() /* Open the normal and bold fonts. */
{
int i ;
font[(int) BFONT] = get_font(fontnames[(int) BFONT], BOLDFONT) ;
font[(int) GFONT] = get_font(fontnames[(int) GFONT], BOARDFONT) ;
font[(int) HFONT] = get_font(fontnames[(int) HFONT], HELPFONT) ;
font[(int) NFONT] = get_font(fontnames[(int) NFONT], NORMALFONT) ;
for (i = 0; i < MAXFONTS; i++)
font_heights[i] = font[i]->max_bounds.ascent +
font[i]->max_bounds.descent ;
}
void
init_graphics(argc, argv)
int *argc ;
char *argv[] ;
{
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL) ;
INSTANCE = xv_unique_key() ;
Reve_Wmain = reve_Wmain_objects_initialize(NULL, NULL) ;
Reve_Wdepth = reve_Wdepth_objects_initialize(NULL, Reve_Wmain->Wmain) ;
Reve_Wprops = reve_Wprops_objects_initialize(NULL, Reve_Wmain->Wmain) ;
Reve_Whelp = reve_Whelp_objects_initialize(NULL, Reve_Wmain->Wmain) ;
Reve_Wload = reve_Wload_objects_initialize(NULL, Reve_Wmain->Wmain) ;
Reve_Wsave = reve_Wsave_objects_initialize(NULL, Reve_Wmain->Wmain) ;
Reve_Wboard = reve_Wboard_objects_initialize(NULL, NULL) ;
dpy = (Display *) xv_get(Reve_Wmain->Wmain, XV_DISPLAY) ;
reve_DB = NULL ;
igc = NULL ;
}
int
init_ws_type()
{
gtype = GXVIEW ; /* Graphics type. */
move_delta = 10 ;
if (xdebug == TRUE) XSynchronize(dpy, TRUE) ;
return(0) ;
}
static void
load_colors() /* Create and load reve color map. */
{
XColor ccol ;
int i, numcolors ;
if (iscolor)
{
numcolors = 0 ;
for (i = 0; i < REVE_USEDCOLORSIZE; i++)
{
if (colstr[i] == NULL ||
(XParseColor(dpy, DefaultColormap(dpy, screen),
colstr[i], &ccol) == 0))
{
ccol.flags = DoRed | DoGreen | DoBlue ;
ccol.red = (unsigned short) (rcols[i] << 8) ;
ccol.green = (unsigned short) (gcols[i] << 8) ;
ccol.blue = (unsigned short) (bcols[i] << 8) ;
}
if (XAllocColor(dpy, DefaultColormap(dpy, screen), &ccol) == True)
palette[numcolors++] = ccol.pixel ;
}
if (numcolors < REVE_USEDCOLORSIZE)
{
FPRINTF(stderr, "%s: cannot allocate colors.\n", progname) ;
exit(1) ;
}
}
}
/* Get the resource databases. These are looked for in the following ways:
*
* Classname file in the app-defaults directory. In this case, Classname
* is Reve.
*
* Classname file in the directory specified by the XUSERFILESEARCHPATH
* or XAPPLRESDIR environment variable.
*
* Property set using xrdb, accessible through the XResourceManagerString
* macro or, if that is empty, the ~/.Xdefaults file.
*
* XENVIRONMENT environment variable or, if not set, .Xdefaults-hostname
* file.
*
* REVEDEFAULTS environment variable or, if not set, the ~/.reverc file.
*/
void
load_resources()
{
XrmDatabase db ;
char *home, name[MAXPATHLEN], *ptr ;
int len ;
home = getenv("HOME") ;
XrmInitialize() ;
STRCPY(name, "/usr/lib/X11/app-defaults/Reve") ;
/* Get applications defaults file, if any. */
db = XrmGetFileDatabase(name) ;
XrmMergeDatabases(db, &reve_DB) ;
/* Merge server defaults, created by xrdb. If nor defined, use ~/.Xdefaults. */
if (XResourceManagerString(dpy) != NULL)
db = XrmGetStringDatabase(XResourceManagerString(dpy)) ;
else
{
SPRINTF(name, "%s/.Xdefaults", home) ;
db = XrmGetFileDatabase(name) ;
}
XrmMergeDatabases(db, &reve_DB) ;
/* Open XENVIRONMENT file or, if not defined, the .Xdefaults, and merge
* into existing database.
*/
if ((ptr = getenv("XENVIRONMENT")) == NULL)
{
SPRINTF(name, "%s/.Xdefaults-", home) ;
len = strlen(name) ;
GETHOSTNAME(name+len, MAXPATHLEN-len) ;
db = XrmGetFileDatabase(name) ;
}
else db = XrmGetFileDatabase(ptr) ;
XrmMergeDatabases(db, &reve_DB) ;
/* Finally merge in Reve defaults via REVEDEFAULTS or, if not defined, the
* ~/.reverc file.
*/
if ((ptr = getenv("REVEDEFAULTS")) == NULL)
{
SPRINTF(name, "%s/.reverc", home) ;
db = XrmGetFileDatabase(name) ;
}
else db = XrmGetFileDatabase(ptr) ;
XrmMergeDatabases(db, &reve_DB) ;
}
void
lock_screen(state)
enum bltype state ;
{}
void
make_canvas() /* Create canvas for game board. */
{
gpw = canvas_paint_window(Reve_Wboard->Bcanvas) ;
XV_SET(canvas_paint_window(Reve_Wboard->Bcanvas),
WIN_CONSUME_EVENTS,
KBD_USE, KBD_DONE, LOC_DRAG,
WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
0,
0) ;
cursor[(int) CANVASCUR] = xv_get(gpw, WIN_CURSOR) ;
xid = (Drawable) xv_get(gpw, XV_XID) ;
screen = DefaultScreen(dpy) ;
root = RootWindow(dpy, screen) ;
foregnd = BlackPixel(dpy, screen) ;
backgnd = WhitePixel(dpy, screen) ;
gc_mask = GCForeground | GCBackground | GCGraphicsExposures ;
gc_val.foreground = foregnd ;
gc_val.background = backgnd ;
gc_val.graphics_exposures = False ;
gc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
ropgc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
XSetFillStyle(dpy, ropgc, FillStippled) ;
stencilgc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
XSetFillStyle(dpy, stencilgc, FillOpaqueStippled) ;
hglass_pr = xv_create(XV_NULL, SERVER_IMAGE,
XV_WIDTH, 16,
XV_HEIGHT, 16,
SERVER_IMAGE_X_BITS, hglass_bits,
0) ;
cursor[(int) HOURGLASS] = xv_create(XV_NULL, CURSOR,
CURSOR_IMAGE, hglass_pr,
0) ;
nocur_pr = xv_create(XV_NULL, SERVER_IMAGE,
XV_WIDTH, 16,
XV_HEIGHT, 16,
SERVER_IMAGE_X_BITS, nocur_bits,
0) ;
cursor[(int) NOCURSOR] = xv_create(XV_NULL, CURSOR,
CURSOR_IMAGE, nocur_pr,
0) ;
if (!monochrome) load_colors() ;
images[(int) P_WHITE] = make_server_image(white_bits) ;
images[(int) P_BLACK] = make_server_image(black_bits) ;
images[(int) S_MOVE] = make_server_image(move_bits) ;
images[(int) S_SUGGEST] = make_server_image(suggest_bits) ;
pid = fork_child() ;
}
/*ARGSUSED*/
void
make_frame(argc, argv) /* Create frame and the panel, buttons, menus. */
int argc ;
char *argv[] ;
{
char mes[MAXLINE] ;
int val ;
opvals[(int) RCLR] = GXclear ;
opvals[(int) RSRC] = GXcopy ;
opvals[(int) RINV] = GXxor ;
XV_SET(Reve_Wboard->Wboard, XV_WIDTH, board_width, 0) ;
XV_SET(Reve_Wboard->Wboard, XV_HEIGHT, board_height, 0) ;
SPRINTF(mes, "%s:", bstone_name) ;
XV_SET(Reve_Wmain->Tblack, PANEL_LABEL_STRING, mes, 0) ;
val = items[(int) BLACK_PLAYS].value ;
XV_SET(Reve_Wmain->Tblack, PANEL_VALUE, player_values[val], 0) ;
SPRINTF(mes, "%s:", wstone_name) ;
XV_SET(Reve_Wmain->Twhite, PANEL_LABEL_STRING, mes, 0) ;
val = items[(int) WHITE_PLAYS].value ;
XV_SET(Reve_Wmain->Twhite, PANEL_VALUE, player_values[val], 0) ;
SPRINTF(mes, "%s to move", bstone_name) ;
XV_SET(Reve_Wmain->Mturn, PANEL_LABEL_STRING, mes, 0) ;
XV_SET(Reve_Wload->Tload, PANEL_VALUE, gamefile, 0) ;
XV_SET(Reve_Wsave->Tsave, PANEL_VALUE, gamefile, 0) ;
if (dtype == XBLACK) val = CP_WHITE ;
else if (dtype == XWHITE) val = CP_BLACK ;
else if (dtype == XBOTH) val = CP_NEITHER ;
XV_SET(Reve_Wprops->Splays, PANEL_CHOICE_STRING, 0, wstone_name, 0) ;
XV_SET(Reve_Wprops->Splays, PANEL_CHOICE_STRING, 1, bstone_name, 0) ;
XV_SET(Reve_Wprops->Splays, PANEL_VALUE, val, 0) ;
XV_SET(Reve_Wprops->Sdifficulty,
PANEL_VALUE, items[(int) DIFF_CHOICE].value,
0) ;
val = ((ANIMATION & 0x1) << 0) +
((DO_BESTMOVE & 0x1) << 1) +
((DO_LAST & 0x1) << 2) +
((SHOW_NOTES & 0x1) << 3) +
((DO_NUMBER & 0x1) << 4) +
((QUICKGAME & 0x1) << 5) +
((SHOW_LEGAL & 0x1) << 6) +
((DO_CLOCK & 0x1) << 7) ;
XV_SET(Reve_Wprops->Soptions, PANEL_VALUE, val, 0) ;
XV_SET(Reve_Wmain->Tblack_time,
PANEL_LABEL_BOLD, FALSE,
PANEL_VALUE, items[(int) BLACK_CLOCK].text,
XV_SHOW, DO_CLOCK,
0) ;
XV_SET(Reve_Wmain->Twhite_time,
PANEL_LABEL_BOLD, FALSE,
PANEL_VALUE, items[(int) WHITE_CLOCK].text,
XV_SHOW, DO_CLOCK,
0) ;
iscolor = ((int) xv_get(Reve_Wmain->Wmain, WIN_DEPTH) > 1) ? 1 : 0 ;
}
/*ARGSUSED*/
void
make_help_window(argc, argv)
int argc ;
char *argv[] ;
{
XV_SET(Reve_Whelp->Whelp, XV_SHOW, help_showing, 0) ;
XV_SET(Reve_Whelp->textpane1,
TEXTSW_FILE_CONTENTS, helpfile,
TEXTSW_READ_ONLY, TRUE,
TEXTSW_FIRST, 0,
TEXTSW_BROWSING, TRUE,
0) ;
}
void
make_icon()
{}
void
make_pieces(width, height)
int width, height ;
{
bborder = BBORDER ;
cell_width = (width - (2 * bborder)) / BOARD_SIZE ;
cell_height = (height - (2 * bborder)) / BOARD_SIZE ;
pieceXmargin = cell_width / 8 ;
pieceYmargin = cell_height / 8 ;
pieceXrad = (cell_width - (2 * pieceXmargin)) / 2 ;
if (pieceXrad > MAXPRAD)
{
pieceXrad = MAXPRAD ;
pieceXmargin = (cell_width - (2 * pieceXrad)) / 2 ;
}
pieceYrad = (cell_height - (2 * pieceYmargin)) / 2 ;
if (pieceYrad > MAXPRAD)
{
pieceYrad = MAXPRAD ;
pieceYmargin = (cell_height - (2 * pieceYrad)) / 2 ;
}
if (igc == NULL)
{
gc_mask = GCForeground | GCBackground | GCGraphicsExposures ;
gc_val.foreground = foregnd ;
gc_val.background = backgnd ;
gc_val.graphics_exposures = False ;
igc = XCreateGC(dpy, images[(int) P_WHITE], gc_mask, &gc_val) ;
}
XSetFunction(dpy, igc, GXclear) ;
XCopyArea(dpy, images[(int) P_WHITE], images[(int) P_WHITE], igc,
0, 0, 2 * MAXPRAD, 2 * MAXPRAD, 0, 0) ;
XCopyArea(dpy, images[(int) P_BLACK], images[(int) P_BLACK], igc,
0, 0, 2 * MAXPRAD, 2 * MAXPRAD, 0, 0) ;
XSetFunction(dpy, igc, GXcopy) ;
XDrawArc(dpy, images[(int) P_WHITE], igc,
0, 0, 2 * pieceXrad - 1, 2 * pieceYrad - 1, 0, 360 * 64) ;
XFillArc(dpy, images[(int) P_BLACK], igc,
0, 0, 2 * pieceXrad - 1, 2 * pieceYrad - 1, 0, 360 * 64) ;
}
static Drawable
make_server_image(image)
unsigned char *image ;
{
Server_image temp ;
temp = xv_create(XV_NULL, SERVER_IMAGE,
XV_WIDTH, 64,
XV_HEIGHT, 64,
SERVER_IMAGE_X_BITS, image,
0) ;
return((int) xv_get(temp, XV_XID, NULL)) ;
}
Menu_item
menu_do(item, op)
Menu_item item ;
Menu_generate op ;
{
char *label ;
if (op == MENU_NOTIFY)
{
label = (char *) xv_get(item, MENU_STRING) ;
if (EQUAL(label, "New")) new_game() ;
else if (EQUAL(label, "Print")) print_game() ;
else if (EQUAL(label, "Load..."))
position_popup(Reve_Wmain->Wmain, Reve_Wload->Wload, P_RIGHT) ;
else if (EQUAL(label, "Save..."))
position_popup(Reve_Wmain->Wmain, Reve_Wsave->Wsave, P_RIGHT) ;
else if (EQUAL(label, "Redo")) redo() ;
else if (EQUAL(label, "Show All")) show_all_moves() ;
else if (EQUAL(label, "Suggest")) suggest() ;
else if (EQUAL(label, "Undo")) undo() ;
}
return(item) ;
}
void
open_reve()
{
XV_SET(Reve_Wboard->Wboard, FRAME_CLOSED, FALSE, 0) ;
}
void
position_popup(parent, child, position)
Frame parent, child ;
int position ;
{
Rect crect, prect ;
int height, width ;
if (((int) xv_get(child, XV_SHOW)) && position == P_RIGHT) return ;
frame_get_rect(parent, &prect) ;
frame_get_rect(child, &crect) ;
height = (int) xv_get(parent, XV_HEIGHT) ;
width = (int) xv_get(parent, XV_WIDTH) ;
switch (position)
{
case P_BELOW : crect.r_left = prect.r_left + FRAME_BORDER_SIZE ;
crect.r_top = prect.r_top + height + FRAME_LABEL_SIZE +
FRAME_BORDER_SIZE ;
break ;
case P_RIGHT : crect.r_left = prect.r_left + width +
(2 * FRAME_BORDER_SIZE) ;
crect.r_top = prect.r_top ;
}
frame_set_rect(child, &crect) ;
if (child != Reve_Wboard->Wboard)
XV_SET(child, FRAME_CMD_PUSHPIN_IN, TRUE, 0) ;
XV_SET(child, XV_SHOW, TRUE, 0) ;
}
void
process_event() /* Process the next canvas event. */
{
int action, id ;
nextc = IGNORE_EVENT ;
action = event_action(cur_event) ;
id = event_id(cur_event) ;
curx = event_x(cur_event) ;
cury = event_y(cur_event) ;
if (id == KBD_DONE || id == LOC_WINEXIT) nextc = EXIT_WINDOW ;
else if (id == LOC_WINENTER) nextc = ENTER_WINDOW ;
else if (id == LOC_DRAG) nextc = MOUSE_MOVING ;
else if (id == WIN_REPAINT) nextc = BOARD_REPAINT ;
else if (event_is_button(cur_event) && event_is_down(cur_event))
{
if (id == MS_LEFT) nextc = LEFT_DOWN ;
else if (id == MS_MIDDLE) nextc = MIDDLE_DOWN ;
else if (id == MS_RIGHT) nextc = RIGHT_DOWN ;
}
else if (event_is_button(cur_event) && event_is_up(cur_event))
{
if (id == MS_LEFT) nextc = LEFT_UP ;
else if (id == MS_MIDDLE) nextc = MIDDLE_UP ;
else if (id == MS_RIGHT) nextc = RIGHT_UP ;
}
else if (event_is_ascii(cur_event))
{
cur_ch = id ;
nextc = KEYBOARD ;
}
else if (action == ACTION_PROPS && event_is_down(cur_event))
position_popup(Reve_Wmain->Wmain, Reve_Wprops->Wprops, P_RIGHT) ;
}
/*ARGSUSED*/
static Notify_value
quit_proc(client, status)
Notify_client client ;
Destroy_status status ;
{
destroy_reve() ;
}
void
raise_reve()
{
wmgr_top(Reve_Wboard->Wboard) ;
}
static Notify_value
read_from_fd(client, fd)
Notify_client client ;
register int fd ;
{
if (fd == socketfd) read_from_sock(fd) ; /* Remote human. */
else if (fd == pipe_io[1][0]) read_from_reve(fd) ; /* Computer. */
set_interval_timer() ;
return(NOTIFY_DONE) ;
}
/*ARGSUSED*/
void
reset_props(item, event)
Panel_item item ;
Event *event ;
{
int val ;
if (dtype == XBLACK) val = CP_WHITE ;
else if (dtype == XWHITE) val = CP_BLACK ;
else if (dtype == XBOTH) val = CP_NEITHER ;
XV_SET(Reve_Wprops->Splays, PANEL_VALUE, val, 0) ;
val = ((ANIMATION & 0x1) << 0) +
((DO_BESTMOVE & 0x1) << 1) +
((DO_LAST & 0x1) << 2) +
((SHOW_NOTES & 0x1) << 3) +
((DO_NUMBER & 0x1) << 4) +
((QUICKGAME & 0x1) << 5) +
((SHOW_LEGAL & 0x1) << 6) +
((DO_CLOCK & 0x1) << 7) ;
XV_SET(Reve_Wprops->Soptions, PANEL_VALUE, val, 0) ;
}
void
set_cursor(ctype)
enum curtype ctype ;
{
if (ctype == NOCURSOR) return ;
XV_SET(gpw, WIN_CURSOR, cursor[(int) ctype], 0) ;
XV_SET(Reve_Wmain->controls1, WIN_CURSOR, cursor[(int) ctype], 0) ;
XV_SET(Reve_Wprops->controls4, WIN_CURSOR, cursor[(int) ctype], 0) ;
}
void
set_depth(item, value, event)
Panel_item item ;
int value ;
Event *event ;
{
position_popup(Reve_Wmain->Wmain, Reve_Wdepth->Wdepth, P_RIGHT) ;
}
/*ARGSUSED*/
void
set_frame(wtype, showing)
enum win_type wtype ;
int showing ;
{}
static void
set_interval_timer()
{
struct itimerval tval ;
tval.it_interval.tv_usec = 0 ; /* Force a timing check every second. */
tval.it_interval.tv_sec = 1 ;
tval.it_value.tv_usec = 0 ;
tval.it_value.tv_sec = 1 ;
notify_set_itimer_func(Reve_Wboard->Wboard, check_clock, ITIMER_REAL,
&tval, (struct itimerval *) 0) ;
}
void
set_profmax(item, event)
Panel_item item ;
Event *event ;
{
change_depth((int) xv_get(Reve_Wdepth->Tdepth, PANEL_VALUE)) ;
level = 1 ;
}
/*ARGSUSED*/
void
set_props(item, event)
Panel_item item ;
Event *event ;
{
int curi, oldval, val ;
if (dtype == XBLACK) oldval = CP_WHITE ;
else if (dtype == XWHITE) oldval = CP_BLACK ;
else if (dtype == XBOTH) oldval = CP_NEITHER ;
val = (int) xv_get(Reve_Wprops->Splays, PANEL_VALUE, 0) ;
if (val == CP_WHITE)
{
dtype = XBLACK ;
play_computer = TRUE ;
items[(int) BLACK_PLAYS].value = HUMAN ;
items[(int) WHITE_PLAYS].value = COMPUTER ;
}
else if (val == CP_BLACK)
{
dtype = XWHITE ;
play_computer = TRUE ;
items[(int) BLACK_PLAYS].value = COMPUTER ;
items[(int) WHITE_PLAYS].value = HUMAN ;
}
else if (val == CP_NEITHER)
{
dtype = XBOTH ;
play_computer = FALSE ;
items[(int) BLACK_PLAYS].value = HUMAN ;
items[(int) WHITE_PLAYS].value = HUMAN ;
}
else if (val == CP_BOTH)
{
XV_SET(Reve_Wprops->Splays, PANEL_VALUE, oldval, 0) ;
message(PANEL_MES, "Computer plays both is not implemented yet.") ;
}
val = items[(int) BLACK_PLAYS].value ;
XV_SET(Reve_Wmain->Tblack, PANEL_VALUE, player_values[val], 0) ;
val = items[(int) WHITE_PLAYS].value ;
XV_SET(Reve_Wmain->Twhite, PANEL_VALUE, player_values[val], 0) ;
if (next_player == BLACK) curi = items[(int) BLACK_PLAYS].value ;
else curi = items[(int) WHITE_PLAYS].value ;
if (curi == COMPUTER)
if ((next_player == BLACK && cmode == BLACK_START) ||
(next_player == WHITE && cmode == WHITE_START))
opponent_move(next_player) ;
val = (int) xv_get(Reve_Wprops->Soptions, PANEL_VALUE, 0) ;
ANIMATION = (val >> 0) & 0x1 ;
DO_BESTMOVE = (val >> 1) & 0x1 ;
DO_LAST = (val >> 2) & 0x1 ;
SHOW_NOTES = (val >> 3) & 0x1 ;
DO_NUMBER = (val >> 4) & 0x1 ;
QUICKGAME = (val >> 5) & 0x1 ;
SHOW_LEGAL = (val >> 6) & 0x1 ;
DO_CLOCK = (val >> 7) & 0x1 ;
XV_SET(Reve_Wmain->Tblack_time, XV_SHOW, DO_CLOCK, 0) ;
XV_SET(Reve_Wmain->Twhite_time, XV_SHOW, DO_CLOCK, 0) ;
XV_SET(Reve_Wprops->Wprops, XV_SHOW, FALSE, 0) ;
}
static Notify_value
sigchldcatcher(client, pid, status, rusage)
Notify_client client ;
int pid ;
union wait *status ;
struct rusage *rusage ;
{
if (WIFEXITED(*status))
{
notify_set_input_func(client, NOTIFY_FUNC_NULL, pipe_io[1][0]) ;
return(NOTIFY_DONE) ;
}
return(NOTIFY_IGNORED) ;
}
/*ARGSUSED*/
void
start_tool(dtype) /* Display window and start the notifier. */
enum disp_type dtype ;
{
set_interval_timer() ;
notify_interpose_destroy_func(Reve_Wmain->Wmain, quit_proc) ;
notify_interpose_destroy_func(Reve_Wboard->Wboard, quit_proc) ;
xv_main_loop(Reve_Wmain->Wmain) ;
}
void
xv_clock(ptype)
enum panel_type ptype ;
{
Xv_opaque handle ;
if (ptype == BLACK_CLOCK) handle = Reve_Wmain->Tblack_time ;
else if (ptype == WHITE_CLOCK) handle = Reve_Wmain->Twhite_time ;
XV_SET(handle, PANEL_VALUE, items[(int) ptype].text, 0) ;
}
void
xv_message(mtype, str)
enum panel_type mtype ;
char *str ;
{
Xv_opaque handle ;
if (mtype == PANEL_MES) handle = Reve_Wmain->Mpanel ;
else if (mtype == EVAL_MES) handle = Reve_Wmain->Meval ;
else if (mtype == SCORE_MES) handle = Reve_Wmain->Mscore ;
else if (mtype == TURN_MES) handle = Reve_Wmain->Mturn ;
XV_SET(handle, PANEL_LABEL_STRING, str, 0) ;
}
void
xv_start_load(item, event)
Panel_item item ;
Event *event ;
{
STRCPY(gamefile, (char *) xv_get(Reve_Wload->Tload, PANEL_VALUE)) ;
load_game() ;
}
void
xv_start_save(item, event)
Panel_item item ;
Event *event ;
{
STRCPY(gamefile, (char *) xv_get(Reve_Wsave->Tsave, PANEL_VALUE)) ;
save_game() ;
}